package com.kagu.wms.module;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.wowza.wms.amf.AMFDataArray;
import com.wowza.wms.amf.AMFDataList;
import com.wowza.wms.amf.AMFPacket;
import com.wowza.wms.application.IApplicationInstance;
import com.wowza.wms.application.WMSProperties;
import com.wowza.wms.client.IClient;
import com.wowza.wms.logging.WMSLogger;
import com.wowza.wms.module.ModuleBase;
import com.wowza.wms.request.RequestFunction;
import com.wowza.wms.stream.IMediaStream;
import com.wowza.wms.stream.IMediaStreamActionNotify2;

public class KaguModule extends ModuleBase {

	private AMFDataArray retArray = new AMFDataArray();
	private IApplicationInstance appInApplicationInstance;
	private static Map<String, String> translations;
//	private static Boolean readManifestProperty;
//	
//	public static Boolean getReadManifestProperty() {
//		return readManifestProperty;
//	}

	static{
		translations = new HashMap<String,String>();
	}
	
	/*TODO remove before release */
	public void doSomething(IClient client, RequestFunction function,
			AMFDataList params) {
		getLogger().info("doSomething");
		sendResult(client, params, "Hello Wowza");
	}
	
	public void getListAvaibleLanguages(IClient client, RequestFunction function, AMFDataList params){
		getLogger().info("getListAvaibleLanguages");
		sendResult(client, params, retArray);
	}
	
	public void setTranslatorLanguage(IClient client, RequestFunction function, AMFDataList params)
	{
		String res = "";
		WMSLogger log = getLogger();
		
		retArray.add(getParamString(params, PARAM1));
		
		String param1 = getParamString(params, PARAM1);
//		int param2 = getParamInt(params, PARAM2);
//		boolean param3 = getParamBoolean(params, PARAM3);
//		Date param4 = getParamDate(params, PARAM4);

		res += "param1: "+param1+"\n";
//		res += "param2: "+param2+"\n";
//		res += "param3: "+param3+"\n";
//		res += "param4: "+param4+"\n";

		log.info(res+" list: "+retArray);

		sendResult(client, params, res);
	}

	public void onAppStart(IApplicationInstance appInstance) {
		this.appInApplicationInstance = appInstance;
		
		
		String fullname = appInstance.getApplication().getName() + "/"
				+ appInstance.getName();
		
		
//		readManifestProperty = prop.getPropertyBoolean("readManifestFromFile", true);
//		System.err.println("boolean prop: "+readManifestProperty);
		
		getLogger().info("onAppStart: " + fullname);
	}

	public void onAppStop(IApplicationInstance appInstance) {
		String fullname = appInstance.getApplication().getName() + "/"
				+ appInstance.getName();
		getLogger().info("onAppStop: " + fullname);
	}

	public void onConnect(IClient client, RequestFunction function,
			AMFDataList params) {
		getLogger().info("onConnect: " + client.getClientId());
		IApplicationInstance applicationInstance = client.getAppInstance();
		getLogger().info("getPublishStreamNames: " + applicationInstance.getPublishStreamNames().size());
	}

	public void onConnectAccept(IClient client) {
		getLogger().info("onConnectAccept: " + client.getClientId());
	}

	public void onConnectReject(IClient client) {
		getLogger().info("onConnectReject: " + client.getClientId());
	}

	public void onDisconnect(IClient client) {
		getLogger().info("onDisconnect: " + client.getClientId());
	}
	
//	public void onPublish(IMediaStream stream, String streamName,
//			boolean isRecord, boolean isAppend) {
//		getLogger().info("onPublish", stream);
//		H264Transcoder tc = new H264Transcoder(stream.getName());
//		tc.start();
//	}
	
	@SuppressWarnings("unchecked")
	public void onStreamCreate(IMediaStream stream) {
		getLogger().info("onStreamCreate by: " + stream.getClientId());
		IMediaStreamActionNotify2 actionNotify  = new StreamListener();
		
		WMSProperties props = stream.getProperties();
		synchronized(props)
		{
			props.put("streamActionNotifier", actionNotify);
		}
		
		stream.addClientListener(actionNotify);
		
	}
	public void onStreamDestroy(IMediaStream stream) {
		getLogger().info("onStreamDestroy by: " + stream.getClientId());
		
		IMediaStreamActionNotify2 actionNotify = null;
		WMSProperties props = stream.getProperties();
		synchronized(props)
		{
			actionNotify = (IMediaStreamActionNotify2)stream.getProperties().get("streamActionNotifier");
		}
		if (actionNotify != null)
		{
			
			stream.removeClientListener(actionNotify);
			removeTranslationsFromList(stream.getName());
			getLogger().info("removeClientListener: "+stream.getSrc()+" stream name: "+stream.getName());
		}
	}
	
	private void removeTranslationsFromList(String name){
		if(name.contains("translation_stream")){
			String value;
			String locale = name.substring(name.lastIndexOf("_")+1, name.length());
			for(int i=0 ; i<retArray.size() ; i++){
				value = (String)retArray.get(i).getValue();
				if(value.equals(locale))
					retArray.remove(i);
			}
			getLogger().info("closed stream have locale: "+locale);
		}
	}
	
//	public static void setTranslationsList(List<String> translationsList) {
//		KaguModule.translationsList = translationsList;
//	}

	public static Map<String, String> getTranslations() {
		return translations;
	}

	class StreamListener  implements IMediaStreamActionNotify2 
	{
		public void onPlay(IMediaStream stream, String streamName, double playStart, double playLen, int playReset) 
		{
//			streamName = stream.getName();
			getLogger().info("Stream Name: " + streamName);
			
		}
		
		public void onMetaData(IMediaStream stream, AMFPacket metaDataPacket) 
		{
			getLogger().info("onMetaData By: " + stream.getClientId());
		}
		
		public void onPauseRaw(IMediaStream stream, boolean isPause, double location) 
		{
			getLogger().info("onPauseRaw By: " + stream.getClientId());
		}

		public void onSeek(IMediaStream stream, double location)
		{
			getLogger().info("onSeek");
		}
		
		public void onStop(IMediaStream stream)
		{
			getLogger().info("onStop By: " + stream.getClientId());
		}
		
		public void onUnPublish(IMediaStream stream, String streamName, boolean isRecord, boolean isAppend)
		{
			getLogger().info("onUNPublish");
			translations.remove(streamName);
		}

		public  void onPublish(IMediaStream stream, String streamName, boolean isRecord, boolean isAppend)
		{
			getLogger().info("####################################################################");
			getLogger().info(
					"onPublish stream: "
							+ streamName
							+ " streams count: "
							+ stream.getStreams().getPublishStreamNames()
									.size());
			if (streamName.startsWith("translation_")) {
				getLogger().info("####################################################################");
				String loc = streamName.substring(streamName.lastIndexOf("_"));
				translations.put(loc, streamName);
//				WMSProperties prop = appInApplicationInstance.getProperties();
//				String publishStreamName = prop.getPropertyStr("publishStreamName");
//				String[] publishBitrateList = prop.getPropertyStr("publishBitrateList").split(",");
//				getLogger().info("  Available bitrates:");
//				if (publishBitrateList != null)
//					for (String bitrate : publishBitrateList) {
//						getLogger().info("   "+bitrate+" Kbps");
//					}
//				getLogger().info("  Xuggle path: "+xugglePath);
//				getLogger().info("  Published stream name: "+publishStreamName);
//				getLogger().info("####################################################################");
//				H264Transcoder tc = new H264Transcoder(publishStreamName+stream.getName());
//				tc.setXugglePath(xugglePath);
//				for (String bitrate : publishBitrateList)
//					tc.addStreamDecoder(bitrate);
//				
//				tc.start();
				
			}
		}
		
		public void onPause(IMediaStream stream, boolean isPause, double location)
		{
			getLogger().info("onPause");
		}
	}

}